using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

namespace Sunny.UI;

public static class RSA
{
	public static byte[] EncryptByPublicKey(string content, string xmlPublicKey)
	{
		using RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
		rSACryptoServiceProvider.FromXmlString(xmlPublicKey);
		RSAParameters rSAParameters = rSACryptoServiceProvider.ExportParameters(includePrivateParameters: false);
		byte[] modulus = rSAParameters.Modulus;
		byte[] exponent = rSAParameters.Exponent;
		BigInteger nNum = new BigInteger(modulus);
		BigInteger keyNum = new BigInteger(exponent);
		return EncryptString(content, keyNum, nNum);
	}

	public static byte[] EncryptByPublicKey(string dataStr, string n, string e)
	{
		BigInteger nNum = new BigInteger(n, 16);
		BigInteger keyNum = new BigInteger(e, 16);
		return EncryptString(dataStr, keyNum, nNum);
	}

	public static string DecryptByPrivateKey(byte[] content, string xmlPrivateKey)
	{
		using RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
		rSACryptoServiceProvider.FromXmlString(xmlPrivateKey);
		RSAParameters rSAParameters = rSACryptoServiceProvider.ExportParameters(includePrivateParameters: true);
		byte[] modulus = rSAParameters.Modulus;
		byte[] d = rSAParameters.D;
		BigInteger nNum = new BigInteger(modulus);
		BigInteger keyNum = new BigInteger(d);
		return DecryptBytes(content, keyNum, nNum);
	}

	public static string DecryptByPrivateKey(byte[] content, string n, string d)
	{
		BigInteger nNum = new BigInteger(n, 16);
		BigInteger keyNum = new BigInteger(d, 16);
		return DecryptBytes(content, keyNum, nNum);
	}

	public static byte[] EncryptByPrivateKey(string content, string xmlPrivateKey)
	{
		using RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
		rSACryptoServiceProvider.FromXmlString(xmlPrivateKey);
		RSAParameters rSAParameters = rSACryptoServiceProvider.ExportParameters(includePrivateParameters: true);
		byte[] modulus = rSAParameters.Modulus;
		byte[] d = rSAParameters.D;
		BigInteger nNum = new BigInteger(modulus);
		BigInteger keyNum = new BigInteger(d);
		return EncryptString(content, keyNum, nNum);
	}

	public static string DecryptByPublicKey(byte[] content, string xmlPublicKey)
	{
		using RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
		rSACryptoServiceProvider.FromXmlString(xmlPublicKey);
		RSAParameters rSAParameters = rSACryptoServiceProvider.ExportParameters(includePrivateParameters: false);
		byte[] modulus = rSAParameters.Modulus;
		byte[] exponent = rSAParameters.Exponent;
		BigInteger nNum = new BigInteger(modulus);
		BigInteger keyNum = new BigInteger(exponent);
		return DecryptBytes(content, keyNum, nNum);
	}

	private static byte[] EncryptString(string dataStr, BigInteger keyNum, BigInteger nNum)
	{
		byte[] bytes = Encoding.UTF8.GetBytes(dataStr);
		int num = bytes.Length;
		int num2 = 0;
		int num3 = 0;
		num2 = ((num % 120 != 0) ? (num / 120 + 1) : (num / 120));
		List<byte> list = new List<byte>();
		for (int i = 0; i < num2; i++)
		{
			num3 = ((num < 120) ? num : 120);
			byte[] array = new byte[num3];
			Array.Copy(bytes, i * 120, array, 0, num3);
			Encoding.UTF8.GetString(array);
			string text = new BigInteger(array).modPow(keyNum, nNum).ToHexString();
			if (text.Length < 256)
			{
				while (text.Length != 256)
				{
					text = "0" + text;
				}
			}
			byte[] array2 = new byte[128];
			for (int j = 0; j < array2.Length; j++)
			{
				array2[j] = Convert.ToByte(text.Substring(j * 2, 2), 16);
			}
			list.AddRange(array2);
			num -= num3;
		}
		return list.ToArray();
	}

	private static string DecryptBytes(byte[] dataBytes, BigInteger KeyNum, BigInteger nNum)
	{
		int num = dataBytes.Length;
		int num2 = 0;
		int num3 = 0;
		num2 = ((num % 128 != 0) ? (num / 128 + 1) : (num / 128));
		List<byte> list = new List<byte>();
		for (int i = 0; i < num2; i++)
		{
			num3 = ((num < 128) ? num : 128);
			byte[] array = new byte[num3];
			Array.Copy(dataBytes, i * 128, array, 0, num3);
			byte[] bytes = new BigInteger(array).modPow(KeyNum, nNum).getBytes();
			Encoding.UTF8.GetString(bytes);
			list.AddRange(bytes);
			num -= num3;
		}
		return Encoding.UTF8.GetString(list.ToArray());
	}
}
